<template>
  <div class="video-container">
    <video
      ref="videoRef"
      :src="videoSrc"
      :poster="posterImage"
      preload="metadata"
      playsinline
      webkit-playsinline
      muted
      @loadedmetadata="onVideoLoaded"
      @canplay="onCanPlay"
      class="video-element"
    >
      您的浏览器不支持视频播放
    </video>
    
    <!-- 自定义封面图片 -->
    <div 
      v-if="showCustomPoster && !videoLoaded" 
      class="video-poster-overlay"
    >
      <img 
        v-if="posterImage" 
        :src="posterImage" 
        alt="视频封面" 
        class="video-poster-image"
      />
      <div v-else class="video-poster-placeholder">
        <svg class="video-play-icon" fill="currentColor" viewBox="0 0 20 20">
          <path d="M6.3 2.841A1.5 1.5 0 004 4.11V15.89a1.5 1.5 0 002.3 1.269l9.344-5.89a1.5 1.5 0 000-2.538L6.3 2.84z"/>
        </svg>
        <span class="video-play-text">点击播放视频</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick, watch, onBeforeUnmount } from 'vue'

const props = defineProps({
  videoSrc: {
    type: String,
    required: true
  },
  posterImage: {
    type: String,
    default: ''
  },
  autoCapturePoster: {
    type: Boolean,
    default: true
  },
  lazyLoad: {
    type: Boolean,
    default: true
  }
})

const videoRef = ref(null)
const videoLoaded = ref(false)
const showCustomPoster = ref(true)
const capturedPoster = ref('')
const isVisible = ref(false)
const observer = ref(null)

const onVideoLoaded = () => {
  console.log('视频元数据已加载')
  // 尝试捕获第一帧作为封面
  if (props.autoCapturePoster && !props.posterImage) {
    captureFirstFrame()
  }
}

const onCanPlay = () => {
  videoLoaded.value = true
  if (!props.lazyLoad || isVisible.value) {
    showCustomPoster.value = false
  }
}

// 捕获视频第一帧作为封面
const captureFirstFrame = async () => {
  if (!videoRef.value) return
  
  try {
    const video = videoRef.value
    
    // 确保视频加载到足够的数据可以捕获帧
    if (video.readyState < 2) {
      await new Promise((resolve) => {
        const loadHandler = () => {
          if (video.readyState >= 2) {
            video.removeEventListener('loadeddata', loadHandler)
            resolve()
          }
        }
        video.addEventListener('loadeddata', loadHandler)
        
        // 设置超时，避免永久等待
        setTimeout(() => {
          video.removeEventListener('loadeddata', loadHandler)
          resolve()
        }, 3000)
      })
    }
    
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    
    canvas.width = video.videoWidth || 320
    canvas.height = video.videoHeight || 180
    
    // 尝试绘制视频帧
    try {
      ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
      
      // 将canvas转换为blob URL并设置为poster
      canvas.toBlob((blob) => {
        if (blob) {
          const posterUrl = URL.createObjectURL(blob)
          capturedPoster.value = posterUrl
          video.poster = posterUrl
          console.log('成功捕获视频首帧')
        }
      }, 'image/jpeg', 0.8)
    } catch (e) {
      console.error('绘制视频帧失败:', e)
    }
  } catch (error) {
    console.error('捕获视频首帧失败:', error)
  }
}

// 强制加载视频元数据
const forceLoadMetadata = () => {
  if (videoRef.value) {
    videoRef.value.load()
    console.log('强制加载视频元数据')
  }
}

// 检查是否为移动端设备
const isMobileDevice = () => {
  return /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
}

// 处理视频可见性变化
const handleVisibilityChange = (entries) => {
  const entry = entries[0]
  isVisible.value = entry.isIntersecting
  
  if (entry.isIntersecting) {
    // 视频进入视口
    console.log('视频进入视口')
    if (videoLoaded.value) {
      showCustomPoster.value = false
    }
    
    // 加载视频数据
    if (videoRef.value) {
      videoRef.value.load()
    }
  } else {
    // 视频离开视口
    console.log('视频离开视口')
    showCustomPoster.value = true
    
    // 暂停视频以节省资源
    if (videoRef.value && !videoRef.value.paused) {
      videoRef.value.pause()
    }
  }
}

// 播放视频
const playVideo = () => {
  if (videoRef.value && videoLoaded.value) {
    videoRef.value.play().catch(err => {
      console.error('视频播放失败:', err)
    })
  }
}

// 暂停视频
const pauseVideo = () => {
  if (videoRef.value) {
    videoRef.value.pause()
  }
}

// 暴露方法供父组件使用
defineExpose({
  playVideo,
  pauseVideo,
  videoElement: videoRef
})

onMounted(async () => {
  await nextTick()
  
  // 为移动设备应用特殊处理
  if (isMobileDevice()) {
    setTimeout(() => {
      forceLoadMetadata()
    }, 100)
  }
  
  // 使用 Intersection Observer 进行懒加载
  if (props.lazyLoad && 'IntersectionObserver' in window) {
    observer.value = new IntersectionObserver(handleVisibilityChange, {
      root: null,
      rootMargin: '0px',
      threshold: 0.1
    })
    
    if (videoRef.value) {
      observer.value.observe(videoRef.value)
    }
  } else {
    // 不支持 IntersectionObserver 时直接设置为可见
    isVisible.value = true
  }
})

onBeforeUnmount(() => {
  // 清理 Intersection Observer
  if (observer.value && videoRef.value) {
    observer.value.unobserve(videoRef.value)
    observer.value.disconnect()
  }
  
  // 清理捕获的海报 URL
  if (capturedPoster.value) {
    URL.revokeObjectURL(capturedPoster.value)
  }
})

// 监听视频源变化，重置状态
watch(() => props.videoSrc, () => {
  videoLoaded.value = false
  showCustomPoster.value = true
  if (videoRef.value) {
    videoRef.value.load()
  }
})
</script>

<style scoped>
.video-container {
  position: relative;
  width: 100%;
  background-color: #000;
  border-radius: 0.5rem;
  overflow: hidden;
}

.video-element {
  display: block;
  width: 100%;
  height: auto;
  object-fit: contain;
}

.video-poster-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.2);
  z-index: 1;
}

.video-poster-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-poster-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: white;
  text-align: center;
}

.video-play-icon {
  width: 3rem;
  height: 3rem;
  margin-bottom: 0.5rem;
  filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.5));
}

.video-play-text {
  font-size: 0.875rem;
  text-shadow: 0 0 2px rgba(0, 0, 0, 0.8);
}

/* 移动端优化 */
@media (max-width: 768px) {
  .video-element {
    object-fit: cover;
  }
}
</style> 